package com.ppt.javappt.component;

import com.ppt.javappt.HelloApplication;
import com.ppt.javappt.util.SystemUtil;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

/**
 * @author KUSA
 * 文本框类
 */

@Getter
@Setter
public class TextBox extends TextArea {

    String fontFamily = "Arial";
    boolean isBold = false;
    boolean isItalic = false;
    boolean isUnderline = false;
    int fontSize = 18;
    String color = "blue";

    // Destroy when Out of Focus
    List<EventHandler<MouseEvent>> handlersDOF = new ArrayList<>();
    // Destroy On Deletion
    List<EventHandler<MouseEvent>> handlersDOD = new ArrayList<>();
    public TextBox(){
        this.setMinSize(10, 10);
        this.setWrapText(true);
        this.setPromptText("在此输入文本");
        this.setStyle();

        // 使用数组以跳过lambda捕获检查
        EventHandler<MouseEvent>[] dragged = new EventHandler[1];
        // 按下鼠标
        EventHandler<MouseEvent> pressed = event ->{
            // 获取局部坐标
            double x = event.getX();
            double y = event.getY();

            // 缩放
            if(x < 10 && y < 10){
                this.setEditable(false);
                // 按下鼠标时的初始值
                double width = this.getWidth();
                double height = this.getHeight();
                Point2D prep = getSlidePosition(event.getSceneX(), event.getSceneY());
                dragged[0] = e ->{
                    // 全局坐标转换为幻灯片坐标
                    Point2D p = getSlidePosition(e.getSceneX(), e.getSceneY());
                    // 相对于初始位置的偏移量
                    double offsetX = prep.getX() - p.getX();
                    double offsetY = prep.getY() - p.getY();
                    // 缩放需不超过对角
                    if (prep.getX() + width > p.getX() && prep.getY() + height > p.getY()) {
                        this.setPosition(p.getX() - x, p.getY() - y);
                        this.setPrefSize(width + offsetX, height + offsetY);
                    }
                };
                // 按下鼠标拖动
                this.addEventFilter(MouseEvent.MOUSE_DRAGGED, dragged[0]);
            }


            // 移动
            else if (!isTextArea(x, y)) {
                this.setEditable(false);
                // 按下时移动鼠标
                 dragged[0] = e ->{
                    // 全局坐标转换为幻灯片坐标
                    Point2D p = getSlidePosition(e.getSceneX(), e.getSceneY());
                    this.setPosition(p.getX() - x, p.getY() - y);
                };
                // 按下鼠标拖动
                this.addEventFilter(MouseEvent.MOUSE_DRAGGED, dragged[0]);
            }
            // 编辑
            else {
                this.setEditable(true);
            }
        };
        // 释放鼠标移除拖动，重置鼠标样式，移除dragged监听器
        EventHandler<MouseEvent> released = event ->{
            if (dragged[0] != null) {
                this.setCursor(HelloApplication.cursor);
                this.removeEventFilter(MouseEvent.MOUSE_DRAGGED, dragged[0]);
            }
        };

        EventHandler<MouseEvent> moved = event ->{
            double x = event.getX();
            double y = event.getY();
            if (x < 10 && y < 10) {
                this.setCursor(Cursor.NW_RESIZE);
            }
            else if (x < 10 || y < 10 || x > this.getWidth() - 10 || y > this.getHeight() - 10) {
                this.setCursor(Cursor.MOVE);
            }
            else {
                this.setCursor(Cursor.TEXT);
            }
        };

        EventHandler<MouseEvent> exited = event ->{
            setCursor(HelloApplication.cursor);
        };

        this.addEventFilter(MouseEvent.MOUSE_MOVED, moved);
        this.addEventFilter(MouseEvent.MOUSE_EXITED, exited);
        this.addEventFilter(MouseEvent.MOUSE_PRESSED, pressed);
        this.addEventFilter(MouseEvent.MOUSE_RELEASED, released);

        this.focusedProperty().addListener((obs, oldVal, newVal) -> {
            if (!newVal) {
                this.setEditable(false);
            }
        });
    }

    public TextBox(double x, double y){
        this();
        this.setPosition(x, y);
        this.setPrefSize(0, 0);
    }

    public TextBox(String text){
        this();
        this.setText(text);
    }

    public void setPosition(double x, double y){
        this.setLayoutX(x);
        this.setLayoutY(y);
    }
    public void setSize(double height,double width){
        this.setHeight(height);
        this.setWidth(width);
    }
    boolean isTextArea(double x, double y){
        if (x < 10 || y < 10 || x > this.getWidth() - 10 || y > this.getHeight() - 10) {
            return false;
        } else {
            return true;
        }
    }

    /** 根据鼠标的全局坐标获取鼠标在幻灯片的坐标 */
    Point2D getSlidePosition(double x, double y){
        return SystemUtil.getInstance().getCurSlideFile().sceneToLocal(x, y);
    }

    /** 更新字体样式 */
    public void setStyle(){
        this.setFont(Font.font(
                fontFamily,
                isBold ? FontWeight.BOLD : FontWeight.NORMAL,
                isItalic ? FontPosture.ITALIC : FontPosture.REGULAR,
                fontSize)
        );
    }

    public void toggleBold(){
        isBold = !isBold;
        this.setStyle();
    }

    public void toggleItalic() {
        isItalic = !isItalic;
        this.setStyle();
    }

    public void toggleUnderline(){
        isUnderline = !isUnderline;
        this.setStyle("-fx-underline: " + isUnderline + ";");
    }

    public void setFontFamily(String s){
        fontFamily = s;
        this.setStyle();
    }

    public void setFontSize(int size){
        fontSize = size;
        this.setStyle();
    }

    public void setColor(String c){
        color = c;
        this.setStyle("-fx-text-fill: " + color + ";");
    }
}
